package com.zkyt.lib_msdk_ext

import com.geoai.mavlink.geoainet.airlink.AirlinkManager
import com.geoai.mavlink.geoainet.airlink.interfaces.IAirlinkComponentConnectedListener
import com.geoai.mavlink.geoainet.airlink.interfaces.IBaseDspListener
import com.geoai.mavlink.geoainet.airlink.interfaces.IBaseRemoteControllerListener
import com.geoai.mavlink.geoainet.base.constant.GEOAIConstant
import com.geoai.mavlink.geoainet.base.mavlinkcore.controller.ProductManager
import com.geoai.mavlink.geoainet.payload.enums.CameraModuleType
import com.geoai.mavlink.geoainet.payload.interfaces.ICameraComponentConnectChangedListener
import com.geoai.mavlink.geoainet.payload.module.camera.AbstractCamera
import com.zkyt.lib_msdk_ext.component.*
import com.zkyt.lib_msdk_ext.component.camera.BaseCameraExt
import com.zkyt.lib_msdk_ext.log.SDKExtLog
import io.reactivex.Observable
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.addTo
import io.reactivex.subjects.BehaviorSubject
import java.util.concurrent.TimeUnit

/**
 * Created by chenyu on 2024/1/9
 * Description:
 */
object ProductManagerExt {
    private const val TAG = "ProductManagerExt"
    private var droneIndex = -1
    private var productManager: ProductManager? = null
    private val isConnectSubject = BehaviorSubject.createDefault(false)
    private val compositeDisposable = CompositeDisposable()

    val cameraManagerExt = BaseCameraExt
    val flycManagerExt = FlyControllerManagerExt
    val missionManagerExt = MissionManagerExt
    val obstacleManagerExt = ObstacleManagerExt
    val rtkManagerExt = RtkManagerExt
    val batteryManagerExt = BatteryManagerExt
    val airLinkManagerExt = AirLinkManagerExt
    val gimbalManagerExt = GimbalManagerExt
    val systemManagerExt = SystemManagerExt
    val crestManagerExt = CrestManagerExt
    // todo 可继续按需添加其他各模块

    /**
     * 初始化一些不需要连接飞机，就已经连接的模块
     */
    fun initEarlyConnectModule() {
        SDKExtLog.i(TAG, "initEarlyConnectModule start!")
        AirlinkManager.getInstance().setAirlinkComponentConnectedListener(object :
            IAirlinkComponentConnectedListener {

            override fun onDspChanged(dsp: IBaseDspListener?) {
                if(dsp != null) {
                    SDKExtLog.i(TAG, "onDspChanged, dsp: $dsp")
                    airLinkManagerExt.init(dsp)
                } else {
                    SDKExtLog.i(TAG, "onDspChanged, dsp disConnected!!")
                    airLinkManagerExt.destroy()
                }
            }

            override fun onRcChanged(rc: IBaseRemoteControllerListener?) {
            }

        })
    }

    fun handleProductConnected(droneIndex: Int, productManager: ProductManager) {
        this.droneIndex = droneIndex
        this.productManager = productManager

        flycManagerExt.init(productManager.flyControllerManager)
        missionManagerExt.init(productManager.missionManager)
        obstacleManagerExt.init(productManager.obstacleManager)
        gimbalManagerExt.init(productManager.gimbalManager)
        systemManagerExt.init(productManager.systemManager)
        crestManagerExt.init(productManager.crestManager)

        isConnectSubject.onNext(true)
        SDKExtLog.i(TAG, "handleProductConnected")
    }

    fun handleComponentConnected(type: Int) {
        if(type == GEOAIConstant.MAVLINK_SYS_HEARTBEAT_TYPE_CAMERA) {
            // MAVLINK_SYS_HEARTBEAT_TYPE_CAMERA这个其实是payload的type，不是相机的type
            // 所以其实是payload的生命周期，不是相机的生命周期，所以需要再监听相机生命周期
            SDKExtLog.i(TAG, "connected, cur payload: ${productManager?.payloadManager}")
            productManager?.payloadManager?.setCameraComponentConnectChangedListener { _, abstractCamera ->
                if(abstractCamera != null) {
                    // 相机连接
                    cameraManagerExt.init(abstractCamera)
                    SDKExtLog.i(TAG, "connected, cur camera Type: ${abstractCamera.cameraModuleName}")
                } else {
                    // 相机断连
                    SDKExtLog.i(TAG, "camera disConnected!!")
                    cameraManagerExt.destroy()
                }
            }

        } else if(type == GEOAIConstant.MAVLINK_SYS_HEARTBEAT_TYPE_BATTERY) {
            batteryManagerExt.init(productManager?.batteryManager!!)
        } else if(type == GEOAIConstant.MAVLINK_SYS_HEARTBEAT_TYPE_RTK) {
            rtkManagerExt.init(productManager?.rtkManager!!)
        }
    }

    fun handleComponentDisconnected(type: Int) {
        if(type == GEOAIConstant.MAVLINK_SYS_HEARTBEAT_TYPE_CAMERA) {
            cameraManagerExt.destroy()
        } else if(type == GEOAIConstant.MAVLINK_SYS_HEARTBEAT_TYPE_BATTERY) {
            batteryManagerExt.destroy()
        } else if(type == GEOAIConstant.MAVLINK_SYS_HEARTBEAT_TYPE_RTK) {
            rtkManagerExt.destroy()
        }
    }

    fun handleProductDisConnected() {
        isConnectSubject.onNext(false)
        cameraManagerExt.destroy()
        flycManagerExt.destroy()
        gimbalManagerExt.destroy()
        missionManagerExt.destroy()
        obstacleManagerExt.destroy()
        rtkManagerExt.destroy()
        batteryManagerExt.destroy()
        systemManagerExt.destroy()
        crestManagerExt.destroy()

        droneIndex = -1
        productManager = null

        SDKExtLog.i(TAG, "handleProductDisConnected")
    }

    fun destroy() {
        compositeDisposable.clear()
    }

    fun getOriginManager(): ProductManager? {
        return productManager
    }

    fun isConnected(): Boolean {
        return isConnectSubject.value ?: false
    }

    fun getConnectedObservable(): Observable<Boolean> = isConnectSubject.hide().distinctUntilChanged()

}